/* * This is eMonocot, a global online biodiversity information resource. * * Copyright © 2011–2015 The Board of Trustees of the Royal Botanic Gardens, Kew and The University of Oxford * * eMonocot is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * eMonocot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * The complete text of the GNU Affero General Public License is in the source repository as the file * ‘COPYING’. It is also available from <http://www.gnu.org/licenses/>. */ package org.emonocot.portal.view; import java.awt.Color; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.el.ELException; import org.apache.commons.lang.StringEscapeUtils; import org.emonocot.api.job.EmonocotTerm; import org.emonocot.api.job.WCSPTerm; import org.emonocot.model.BaseData; import org.emonocot.model.Description; import org.emonocot.model.Distribution; import org.emonocot.model.Identifier; import org.emonocot.model.Image; import org.emonocot.model.MeasurementOrFact; import org.emonocot.model.Reference; import org.emonocot.model.Taxon; import org.emonocot.model.TypeAndSpecimen; import org.emonocot.model.VernacularName; import org.emonocot.model.compare.AlphabeticalTaxonComparator; import org.emonocot.model.compare.DistributionComparator; import org.emonocot.model.compare.LocationComparator; import org.emonocot.model.compare.ReferenceBasedDescriptionComparator; import org.emonocot.model.constants.DescriptionType; import org.emonocot.model.constants.Location; import org.emonocot.model.constants.Status; import org.emonocot.model.convert.ClassToStringConverter; import org.emonocot.model.convert.PermissionToStringConverter; import org.emonocot.model.registry.Organisation; import org.emonocot.pager.FacetName; import org.emonocot.pager.Page; import org.emonocot.portal.view.bibliography.Bibliography; import org.emonocot.portal.view.bibliography.SimpleBibliographyImpl; import org.emonocot.portal.view.provenance.ProvenanceHolder; import org.emonocot.portal.view.provenance.ProvenanceManager; import org.emonocot.portal.view.provenance.ProvenanceManagerImpl; import org.gbif.dwc.terms.Term; import org.gbif.dwc.terms.IucnTerm; import org.gbif.ecat.voc.EstablishmentMeans; import org.gbif.ecat.voc.OccurrenceStatus; import org.gbif.ecat.voc.Rank; import org.gbif.ecat.voc.TaxonomicStatus; import org.hibernate.proxy.HibernateProxy; import org.joda.time.DateTime; import org.joda.time.Duration; import org.joda.time.Interval; import org.joda.time.Period; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import org.joda.time.format.PeriodFormat; import org.joda.time.format.PeriodFormatter; import org.joda.time.format.PeriodFormatterBuilder; import org.ocpsoft.prettytime.PrettyTime; import org.springframework.batch.core.BatchStatus; import org.springframework.core.convert.support.DefaultConversionService; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.GeometryFactory; /** * * @author ben * */ public class Functions { private static DateTimeFormatter timeOnlyFormatter = DateTimeFormat .forPattern("HH:mm:ss"); private static DefaultConversionService conversionService = new DefaultConversionService(); private static double MAX_DEGREES_LATITUDE = 180.0; private static Color[] baseColors = { new Color(255, 210, 54), new Color(213, 12, 84), new Color(111, 148, 73), new Color(0, 116, 204), new Color(97, 102, 104) }; static { conversionService.addConverter(new PermissionToStringConverter()); conversionService.addConverter(new ClassToStringConverter()); } private Functions() { } public static String escape(final String string) { return StringEscapeUtils.escapeXml(string); } public static Boolean isChildFacet(String parent, String facet) { try { FacetName parentFacetName = FacetName.fromString(parent); FacetName facetName = FacetName.fromString(facet); if(parentFacetName.getChild() == null || !parentFacetName.getChild().equals(facetName)) { return Boolean.FALSE; } else { return Boolean.TRUE; } } catch(IllegalArgumentException iae) { return Boolean.FALSE; } } /** * * @param string * Set the string to strip xml from * @return an stripped string */ public static String stripXml(String string) { return string.replaceAll("\\<.*?>", ""); } public static String printTimeOnly(DateTime dateTime) { if (dateTime == null) { return null; } else { return timeOnlyFormatter.print(dateTime.minusHours(1)); } } /** * @param status * Set the status * @return true if the job is startable */ public static Boolean isStartable(BatchStatus status) { if (status == null) { return Boolean.TRUE; } else { switch (status) { case STARTED: case STARTING: case STOPPING: case UNKNOWN: return Boolean.FALSE; case COMPLETED: case FAILED: case STOPPED: default: return Boolean.TRUE; } } } public static Map<String, Map<String, String>> phylocolors( Collection<Taxon> taxa) { Map<String, Map<String, String>> phylocolors = new HashMap<String, Map<String, String>>(); Set<String> orders = new HashSet<String>(); Set<String> families = new HashSet<String>(); Set<String> genera = new HashSet<String>(); for (Taxon t : taxa) { if (t.getOrder() != null && !t.getOrder().isEmpty()) { orders.add(t.getOrder()); } if (t.getFamily() != null && !t.getFamily().isEmpty()) { families.add(t.getFamily()); } if (t.getGenus() != null && !t.getGenus().isEmpty()) { genera.add(t.getGenus()); } } phylocolors.put("order", getColorMap(orders)); phylocolors.put("family", getColorMap(families)); phylocolors.put("genus", getColorMap(genera)); return phylocolors; } private static Map<String, String> getColorMap(Set<String> categories) { int numberOfCategories = categories.size(); float increment = 0.5f / (numberOfCategories / 5); Map<String, String> colorMap = new HashMap<String, String>(); int i = 0; for (String category : categories) { Color baseColor = baseColors[i % 5]; int offset = i / 5; if (offset > 0) { float hsbVals[] = Color.RGBtoHSB(baseColor.getRed(), baseColor.getGreen(), baseColor.getBlue(), null); Color highlight = Color.getHSBColor(hsbVals[0], hsbVals[1], offset * increment * (1f + hsbVals[2])); colorMap.put(category, String.format("#%06X", (0xFFFFFF & highlight.getRGB()))); } else { colorMap.put(category, String.format("#%06X", (0xFFFFFF & baseColor.getRGB()))); } i++; } return colorMap; } public static String evaluate(String expressionString, PageContext pageContext) throws ELException { return (String) pageContext.getExpressionEvaluator().evaluate( expressionString, String.class, pageContext.getVariableResolver(), null); } static PrettyTime prettyTime = new PrettyTime(); public static String prettyTime(DateTime dateTime) { if (dateTime == null) { return null; } else { return prettyTime.format(dateTime.toDate()); } } /** * * @param rank * Set the rank * @return the abbreviated rank */ public static String abbreviateRank(Rank rank) { if (rank == null) { return null; } else { switch (rank) { case VARIETY: return "var"; case InfraspecificName: return "infrasp"; case SUBSPECIES: return "ssp"; case SPECIES: return "sp"; case GENUS: return "gen"; case Subtribe: return "subtrib"; case Tribe: return "trib"; case Subfamily: return "subfam"; case FAMILY: return "fam"; default: return Rank.toAbbreviation(rank); } } } /** * * @param rank * Set the rank * @return the formatted rank */ public static String formatRank(Rank rank) { if (rank == null) { return null; } else { String r = rank.name(); return r.substring(0, 1).toUpperCase() + r.substring(1).toLowerCase(); } } /** * @param rank * Set the rank * @return true if the rank is infraspecific */ public static Boolean isInfraspecific(Rank rank) { if (rank == null) { return Boolean.FALSE; } else { if (rank.compareTo(Rank.SPECIES) > 0) { return Boolean.TRUE; } else { return Boolean.FALSE; } } } /** * @param taxon * Set the taxon * @return the protolog link of the taxon if it exists */ public static Identifier getProtologLink(Taxon taxon) { for (Identifier identifier : taxon.getIdentifiers()) { if (identifier.getSubject() != null && identifier.getSubject().equals("Protolog")) { return identifier; } } return null; } /** * @param preferred * Set the preferred * @return the preferred name of the vernacularNames */ public static VernacularName getPreferred(Taxon taxon) { for (VernacularName vernacular : taxon.getVernacularNames()) { if (vernacular.getPreferredName() == true) { return vernacular; } } for (VernacularName vernacular : taxon.getVernacularNames()) { return vernacular; } return null; } /** * @param taxon * Set the taxon * @return true if the taxon is a synonym */ public static Boolean isSynonym(Taxon taxon) { if (taxon.getTaxonomicStatus() == null) { return false; } else { switch (taxon.getTaxonomicStatus()) { case Synonym: case Heterotypic_Synonym: case Homotypic_Synonym: case DeterminationSynonym: case IntermediateRankSynonym: case Proparte_Synonym: return true; case Accepted: case Doubtful: case Misapplied: default: return false; } } } /** * @param taxon * Set the taxon * @return true if the taxon is accepted */ public static Boolean isAccepted(Taxon taxon) { if (taxon.getTaxonomicStatus() == null) { return false; } else { return taxon.getTaxonomicStatus().equals(TaxonomicStatus.Accepted); } } /** * * @return the list of features */ public static DescriptionType[] features() { return DescriptionType.values(); } /** * @param region * Set the region * @return the country code or null if the distribution is at regional level * or above */ public static String country(Location region) { if (region == null || region.getLevel().equals(2) || region.getLevel().equals(0)) { return null; } else { return region.getCode(); } } /** * @param region * Set the region * @return the region code or null if the distribution is at continent level */ public static String region(Location region) { if (region == null || region.getLevel().equals(0)) { return null; } else if (region.getLevel().equals(1)) { return region.getCode(); } else { return region.getParent().getCode(); } } /** * * @param taxon * Set the taxon * @param feature * Set the feature * @return a Content object, or null */ public static List<Description> content(Taxon taxon, DescriptionType feature) { List<Description> descriptions = new ArrayList<Description>(); for (Description d : taxon.getDescriptions()) { if (d.getType().equals(feature)) { descriptions.add(d); } } Collections.sort(descriptions,new ReferenceBasedDescriptionComparator()); return descriptions; } /** * * @param taxon * Set the taxon * @return the list of regions we have distribution records for */ public static List<Location> regions(Collection<Distribution> distribution) { List<Location> regions = new ArrayList<Location>(); for (Distribution d : distribution) { regions.add(d.getLocation()); } LocationComparator comparator = new LocationComparator(); Collections.sort(regions, comparator); return regions; } /** * * @param taxa * Set the taxa to sort * @return the list of taxa sorted alphabetically */ public static List<Taxon> sort(Collection<Taxon> taxa) { Comparator<Taxon> comparator = new AlphabeticalTaxonComparator(); List<Taxon> list = new ArrayList<Taxon>(taxa); Collections.sort(list, comparator); return list; } public static String duration(Duration duration) { if (duration == null) { return null; } else { return PeriodFormat.getDefault().print(new Period(duration)); } } /** * Returns a string which can be passed to the EDIT Map REST Service to * produce a distribution map. * * http://dev.e-taxonomy.eu/trac/wiki/MapRestServiceApi * * TODO only assumes the status "present" at the moment. TODO assumes that * level 3 is the finest level of detail * * @param taxon * Set the taxon * @return a string which can be passed to the map rest service */ public static String map(Taxon taxon) { StringBuffer stringBuffer = new StringBuffer(); List<Location> continents = new ArrayList<Location>(); List<Location> regions = new ArrayList<Location>(); List<Location> countries = new ArrayList<Location>(); for (Distribution distribution : taxon.getDistribution()) { if (distribution.getLocation().getLevel().equals(0)) { continents.add(distribution.getLocation()); } else if (distribution.getLocation().getLevel().equals(1)) { regions.add(distribution.getLocation()); } else { countries.add(distribution.getLocation()); } } boolean hasLevel1 = !continents.isEmpty(); boolean hasLevel2 = !regions.isEmpty(); boolean hasLevel3 = !countries.isEmpty(); if (hasLevel1) { stringBuffer.append("tdwg1:"); appendAreas(stringBuffer, Status.present, continents); if (hasLevel2 || hasLevel3) { stringBuffer.append("||"); } } if (hasLevel2) { stringBuffer.append("tdwg2:"); appendAreas(stringBuffer, Status.present, regions); if (hasLevel3) { stringBuffer.append("||"); } } if (hasLevel3) { stringBuffer.append("tdwg3:"); appendAreas(stringBuffer, Status.present, countries); } return stringBuffer.toString(); } /** * * @param stringBuffer * a stringbuffer containing a partially constructed url fragment * @param status * the status of the taxon in the following regions * @param areas * a list of regions */ private static void appendAreas(StringBuffer stringBuffer, Status status, List<? extends Location> areas) { stringBuffer.append(status.name() + ":"); stringBuffer.append(areas.get(0).getCode()); for (int i = 1; i < areas.size(); i++) { stringBuffer.append("," + areas.get(i).getCode()); } } public static List<String> sortItems() { List<String> sortItems = new ArrayList<String>(); sortItems.add("searchable.label_sort_asc"); sortItems.add("base.created_dt_desc"); sortItems.add("_asc"); return sortItems; } public static List<String> annotationSortItems() { List<String> sortItems = new ArrayList<String>(); sortItems.add("annotation.type_s_asc"); sortItems.add("annotation.code_s_asc"); sortItems.add("annotation.record_type_s_asc"); sortItems.add("base.created_dt_desc"); sortItems.add("_asc"); return sortItems; } public static List<String> organisationItems() { List<String> sortItems = new ArrayList<String>(); sortItems.add("searchable.label_sort_asc"); sortItems.add("_asc"); return sortItems; } public static List<String> commentItems() { List<String> sortItems = new ArrayList<String>(); sortItems.add("comment.created_dt_desc"); sortItems.add("_asc"); return sortItems; } public static List<String> resourceSortItems() { List<String> sortItems = new ArrayList<String>(); sortItems.add("resource.last_harvested_dt_desc"); sortItems.add("resource.last_harvested_dt_asc"); sortItems.add("resource.duration_l_desc"); sortItems.add("resource.duration_l_asc"); sortItems.add("resource.records_read_l_asc"); sortItems.add("resource.records_read_l_desc"); sortItems.add("base.created_dt_desc"); sortItems.add("_asc"); return sortItems; } private static Pattern pattern = Pattern .compile("\\[(.*?) TO (.*?)\\+(\\d)(\\w+)\\]"); private static DateTimeFormatter solrDateTimeFormatter = DateTimeFormat .forPattern("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"); public static String formatDateRange(String dateRange) { Matcher matcher = pattern.matcher(dateRange); if (matcher.matches()) { String beginningString = matcher.group(1); String endString = matcher.group(2); DateTime beginning = solrDateTimeFormatter .parseDateTime(beginningString); DateTime end = solrDateTimeFormatter.parseDateTime(endString); Integer gap = Integer.parseInt(matcher.group(3)); String increment = matcher.group(4); DateTimeFormatter dateTimeFormatter = null; switch (increment) { case "DAY": end = end.plusDays(gap); dateTimeFormatter = DateTimeFormat.shortDate(); break; case "WEEK": end = end.plusWeeks(gap); dateTimeFormatter = DateTimeFormat.shortDate(); break; case "MONTH": end = end.plusMonths(gap); dateTimeFormatter = DateTimeFormat.forPattern("yyyy/MM"); break; case "YEAR": end = end.plusYears(gap); dateTimeFormatter = DateTimeFormat.forPattern("yyyy"); break; } return dateTimeFormatter.print(beginning) + " - " + dateTimeFormatter.print(end); } else { return dateRange; } } /** * * @param object * the object, which may be a proxy or may not * @return the object */ public static Object deproxy(Object object) { if (object instanceof HibernateProxy) { return ((HibernateProxy) object).getHibernateLazyInitializer() .getImplementation(); } else { return object; } } /** * * @param start * Set the start date * @param end * Set the end date * @return a formatted period */ public static String formatPeriod(Date start, Date end) { DateTime startDate = new DateTime(start); DateTime endDate = new DateTime(end); Period period = new Interval(startDate, endDate).toPeriod(); PeriodFormatter formatter = new PeriodFormatterBuilder() .minimumPrintedDigits(2).appendHours().appendSeparator(":") .appendMinutes().appendSeparator(":").appendSeconds() .toFormatter(); return formatter.print(period); } /** * * @param date * Set the date * @return a formatted date */ public static String formatDate(Date date) { DateTime dateTime = new DateTime(date); return DateTimeFormat.forStyle("SS").print(dateTime); } /** * * @param list * Set the list * @param index * Set the index * @return a sublist starting at index */ public static List<Taxon> sublist(List<Taxon> list, Integer index) { return list.subList(index, list.size()); } /** * * @param string * The string to split * @param pattern * The pattern to split upon * @return an array of substrings */ public static List<String> split(String string, String pattern) { return Arrays.asList(string.split(pattern)); } /** * * @param object * the object to convert * @return a string */ public static String convert(Object object) { return conversionService.convert(object, String.class); } /** * To cope with the fact that we can't use the reserved word 'class' in JSP * Expression language and Tomcat 7 complains. * * @param object * the object to convert * @return the fully qualified class name */ public static String convertClazz(Object object) { return conversionService.convert(object.getClass(), String.class); } /** * * @param taxon * Set the taxon * @return the bibliography */ public static Bibliography bibliography(Taxon taxon) { Bibliography bibliography = new SimpleBibliographyImpl(); bibliography.setReferences(taxon); return bibliography; } /** * * @param bibliography * Set the bibliography * @param reference * Set the reference * @return the citation key */ public static String citekey(Bibliography bibliography, Reference reference) { return bibliography.getKey(reference); } public static SortedSet<String> citekeys(Bibliography bibliography, Collection<Distribution> distributions) { return bibliography.getKeys(distributions); } public static Reference getref(Bibliography bibliography, String key) { return bibliography.getReference(key); } /** * * @param taxon * Set the taxon * @return the provenance */ public static ProvenanceManager provenance(BaseData data) { ProvenanceManager provenance = new ProvenanceManagerImpl(); provenance.setProvenance(data); return provenance; } /** * * @param provenance * Set the provenance * @param data * Set the data * @return the provenance key */ public static String provenancekey(ProvenanceManager provenance, BaseData data) { return provenance.getKey(data); } public static String initialtokey(String initial){ return initial.substring(initial.length() - 1).toUpperCase(); } /** * * @param provenance * Set the provenance * @param data * Set the data * @return the provenance initial */ public static String provenanceinitial(ProvenanceManager provenance, BaseData data) { String key = provenance.getKey(data).toUpperCase(); String orgname = data.getAuthority().getTitle(); String initials = ""; for (int i = 0, n = orgname.length(); i < n; i++){ if (Character.isUpperCase(orgname.charAt(i))){ initials += orgname.charAt(i); } } initials += "." + key; return initials; } public static SortedSet<String> provenanceinitials(ProvenanceManager provenance, Collection<BaseData> data) { SortedSet<String> initials = new TreeSet<String>(); for(BaseData baseData : data) { initials.add(provenanceinitial(provenance, baseData)); } return initials; } public static SortedSet<String> provenancekeys( ProvenanceManager provenance, Collection<BaseData> data) { return provenance.getKeys(data); } public static SortedSet<Organisation> provenancesources( ProvenanceManager provenance) { return provenance.getSources(); } public static SortedSet<ProvenanceHolder> provenancedata( ProvenanceManager provenance, Organisation organisation) { return provenance.getProvenanceData(organisation); } /** * * @param pager * Set the pager * @param facet * Set the facet name * @return true, if the facet is selected */ public static Boolean isFacetSelected(Page pager, String facet) { return pager.isFacetSelected(facet); } public static String escapeHtmlIdentifier(String identifier) { return identifier.replaceAll("\\.", "").replaceAll("_", ""); } public static Set<Organisation> sources(Taxon taxon) { Set<Organisation> sources = new HashSet<Organisation>(); sources.add(taxon.getAuthority()); for (Description d : taxon.getDescriptions()) { sources.add(d.getAuthority()); } for (Distribution d : taxon.getDistribution()) { sources.add(d.getAuthority()); } for (Image i : taxon.getImages()) { sources.add(i.getAuthority()); } for (Reference r : taxon.getReferences()) { sources.add(r.getAuthority()); } for (Identifier i : taxon.getIdentifiers()) { sources.add(i.getAuthority()); } for (TypeAndSpecimen s : taxon.getTypesAndSpecimens()) { sources.add(s.getAuthority()); } for (MeasurementOrFact f : taxon.getMeasurementsOrFacts()) { sources.add(f.getAuthority()); } for (VernacularName n : taxon.getVernacularNames()) { sources.add(n.getAuthority()); } return sources; } private static OccurrenceStatus toPresentAbsent(OccurrenceStatus o) { if (o == null) { return OccurrenceStatus.Present; } else { switch (o) { case Absent: case Excluded: return OccurrenceStatus.Absent; case Present: case Common: case Rare: case Irregular: case Doubtful: default: return OccurrenceStatus.Present; } } } private static EstablishmentMeans toNativeIntroduced(EstablishmentMeans e) { if (e == null) { return EstablishmentMeans.Native; } else { switch (e) { case Introduced: case Invasive: case Managed: case Naturalised: return EstablishmentMeans.Introduced; case Uncertain: case Native: default: return EstablishmentMeans.Native; } } } /** * * @param taxon * Set the taxon * @return the bounding box */ public static String boundingBox(Taxon taxon, OccurrenceStatus occurrenceStatus) { List<Geometry> list = new ArrayList<Geometry>(); for (Distribution d : taxon.getDistribution()) { if (toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus)) { list.add(d.getLocation().getEnvelope()); } } GeometryCollection geometryCollection = new GeometryCollection( list.toArray(new Geometry[list.size()]), new GeometryFactory()); Coordinate[] envelope = geometryCollection.getEnvelope() .getCoordinates(); StringBuffer boundingBox = new StringBuffer(); boundingBox.append(Math.round(envelope[0].x)); boundingBox.append(","); boundingBox.append(Math.round(envelope[0].y)); boundingBox.append(","); boundingBox.append(Math.round(envelope[2].x)); boundingBox.append(","); boundingBox.append(Math.round(envelope[2].y)); return boundingBox.toString(); } public static Boolean hasDistribution(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { for (Distribution d : taxon.getDistribution()) { if (toPresentAbsent(d.getOccurrenceStatus()).equals(occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals(establishmentMeans)) { return Boolean.TRUE; } } return Boolean.FALSE; } public static Collection<Distribution> getDistribution(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { SortedSet<Distribution> distribution = new TreeSet<Distribution>(new DistributionComparator()); for (Distribution d : taxon.getDistribution()) { if (toPresentAbsent(d.getOccurrenceStatus()).equals(occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals(establishmentMeans)) { distribution.add(d); } } return distribution; } /** * * @param taxon * Set the taxon * @return true if the taxon has level 1 features, false otherwise */ public static Boolean hasLevel1Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(0) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { return Boolean.TRUE; } } return Boolean.FALSE; } /** * * @param taxon * Set the taxon * @return the level 1 feature identifiers (FIDs) */ public static String getLevel1Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { boolean first = true; StringBuffer features = new StringBuffer(); for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(0) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { if (!first) { features.append(","); } features.append(d.getLocation().getFeatureId()); first = false; } } return features.toString(); } /** * * @param taxon * Set the taxon * @return true if the taxon has level 2 features, false otherwise */ public static Boolean hasLevel2Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(1) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { return Boolean.TRUE; } } return Boolean.FALSE; } /** * * @param taxon * Set the taxon * @return the level 2 feature identifiers (FIDs) */ public static String getLevel2Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { boolean first = true; StringBuffer features = new StringBuffer(); for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(1) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { if (!first) { features.append(","); } features.append(d.getLocation().getFeatureId()); first = false; } } return features.toString(); } /** * * @param taxon * Set the taxon * @return true if the taxon has level 3 features, false otherwise */ public static Boolean hasLevel3Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(2) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { return Boolean.TRUE; } } return Boolean.FALSE; } public static Boolean hasLevel4Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(3) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { return Boolean.TRUE; } } return Boolean.FALSE; } /** * * @param taxon * Set the taxon * @return the level 3 feature identifiers (FIDs) */ public static String getLevel3Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { boolean first = true; StringBuffer features = new StringBuffer(); for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(2) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { if (!first) { features.append(","); } features.append(d.getLocation().getFeatureId()); first = false; } } return features.toString(); } public static String getLevel4Features(Taxon taxon, OccurrenceStatus occurrenceStatus, EstablishmentMeans establishmentMeans) { boolean first = true; StringBuffer features = new StringBuffer(); for (Distribution d : taxon.getDistribution()) { if (d.getLocation().getLevel().equals(3) && toPresentAbsent(d.getOccurrenceStatus()).equals( occurrenceStatus) && toNativeIntroduced(d.getEstablishmentMeans()).equals( establishmentMeans)) { if (!first) { features.append(","); } features.append(d.getLocation().getFeatureId()); first = false; } } return features.toString(); } /** * * @return the list of measurements or facts */ public static Term[] measurements() { return new Term[] { WCSPTerm.Habitat, WCSPTerm.Lifeform, IucnTerm.threatStatus, EmonocotTerm.SRLI }; } /** * * @param taxon * Set the taxon * @param measurement * Set the measurement * @return a Content object, or null */ public static Set<MeasurementOrFact> facts(Taxon taxon, Term measurements) { Set<MeasurementOrFact> facts = new HashSet<MeasurementOrFact>(); for (MeasurementOrFact m : taxon.getMeasurementsOrFacts()) { if (m.getMeasurementType().equals(measurements)) { facts.add(m); } } return facts; } }